import { useState, useEffect, useRef, useCallback } from 'react'
import { createWebSocketConnection } from '../services/api'
import toast from 'react-hot-toast'

export const useWebSocket = (runId) => {
  const [messages, setMessages] = useState([])
  const [connectionStatus, setConnectionStatus] = useState('disconnected')
  const [isComplete, setIsComplete] = useState(false)
  const [reportLinks, setReportLinks] = useState({})
  const wsRef = useRef(null)
  const reconnectTimeoutRef = useRef(null)
  const reconnectAttemptsRef = useRef(0)

  const maxReconnectAttempts = 3

  const addMessage = useCallback((message) => {
    setMessages(prev => [...prev, {
      ...message,
      id: Date.now() + Math.random(),
      timestamp: message.timestamp || new Date().toISOString()
    }])
  }, [])

  const connect = useCallback(() => {
    if (!runId || wsRef.current?.readyState === WebSocket.OPEN) {
      return
    }

    try {
      setConnectionStatus('connecting')
      const ws = createWebSocketConnection(runId)
      wsRef.current = ws

      ws.onopen = () => {
        console.log(`[WebSocket] Connected to run ${runId}`)
        setConnectionStatus('connected')
        reconnectAttemptsRef.current = 0
        toast.success('已连接到执行监控')
      }

      ws.onmessage = (event) => {
        try {
          const data = JSON.parse(event.data)
          console.log('[WebSocket] Received:', data)
          
          addMessage(data)

          // 处理特殊消息类型
          if (data.type === 'completion') {
            setIsComplete(true)
            setReportLinks(data.report_links || {})
            setConnectionStatus('completed')
            
            if (data.success) {
              toast.success('测试执行完成!')
            } else {
              toast.error(`测试执行失败 (退出代码: ${data.return_code})`)
            }
          }
        } catch (error) {
          console.error('[WebSocket] Failed to parse message:', error)
        }
      }

      ws.onclose = (event) => {
        console.log(`[WebSocket] Connection closed:`, event.code, event.reason)
        setConnectionStatus('disconnected')
        
        // 如果不是正常关闭且未完成，尝试重连
        if (event.code !== 1000 && !isComplete && reconnectAttemptsRef.current < maxReconnectAttempts) {
          reconnectAttemptsRef.current++
          const delay = Math.pow(2, reconnectAttemptsRef.current) * 1000 // 指数退避
          
          console.log(`[WebSocket] Attempting reconnect ${reconnectAttemptsRef.current}/${maxReconnectAttempts} in ${delay}ms`)
          toast(`连接断开，${delay/1000}秒后重试 (${reconnectAttemptsRef.current}/${maxReconnectAttempts})`)
          
          reconnectTimeoutRef.current = setTimeout(() => {
            connect()
          }, delay)
        } else if (reconnectAttemptsRef.current >= maxReconnectAttempts) {
          toast.error('连接失败，已达到最大重试次数')
        }
      }

      ws.onerror = (error) => {
        console.error('[WebSocket] Error:', error)
        toast.error('WebSocket连接出错')
      }

    } catch (error) {
      console.error('[WebSocket] Failed to create connection:', error)
      setConnectionStatus('error')
      toast.error('无法建立WebSocket连接')
    }
  }, [runId, isComplete, addMessage])

  const disconnect = useCallback(() => {
    if (reconnectTimeoutRef.current) {
      clearTimeout(reconnectTimeoutRef.current)
      reconnectTimeoutRef.current = null
    }
    
    if (wsRef.current) {
      wsRef.current.close(1000, 'User disconnected')
      wsRef.current = null
    }
    
    setConnectionStatus('disconnected')
  }, [])

  const clearMessages = useCallback(() => {
    setMessages([])
    setIsComplete(false)
    setReportLinks({})
  }, [])

  // 自动连接
  useEffect(() => {
    if (runId) {
      connect()
    }

    return () => {
      disconnect()
    }
  }, [runId, connect, disconnect])

  // 组件卸载时清理
  useEffect(() => {
    return () => {
      disconnect()
    }
  }, [disconnect])

  return {
    messages,
    connectionStatus,
    isComplete,
    reportLinks,
    connect,
    disconnect,
    clearMessages,
  }
}